#ifndef __LIST_H__
#define __LIST_H__

#include <cstddef>

struct ListNode
{
    ListNode* next;
    int data;

    ListNode(const int value) : data(value), next(nullptr) {}
};

ListNode* createList(const int arr[], const int n);

void deleteList(ListNode*& head);

void printList(const ListNode* head);

template <typename T>
class List
{
    struct ListNodeV2
    {
        ListNodeV2* next;
        T data;
        ListNodeV2(const T& value) : data(value), next(nullptr) {}
    };

  public:
    List();
    ~List() { clear(); }

    T& front();
    const T& front() const;
    T& back();
    const T& back() const;

    bool empty() const;
    size_t size() const;

    void push_back();
    void push_front();

    void pop_back();
    void pop_front();

    void insert(size_t pos, const T& data);
    void erase(size_t pos);

    void clear();

    void reverse();
    void sort();

  private:
    ListNodeV2* head;
    ListNodeV2* tail;
};

#endif  //__LIST_H__